
package com.hlkj.pay.app.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.framework.mybatis.core.query.QueryWrapperX;
import com.hlkj.framework.mybatis.core.utils.MyBatisUtils;
import com.hlkj.pay.app.adminuser.IAdminUserAppService;
import com.hlkj.pay.app.order.IPayOrderAppService;
import com.hlkj.pay.app.order.IReceiveOrderAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.common.OpenApiResultCode;
import com.hlkj.pay.dto.LocalAdminUserRequest;
import com.hlkj.pay.dto.LocalMerchantRequest;
import com.hlkj.pay.dto.order.OrderReceiveDto;
import com.hlkj.pay.dto.order.OrderReceiveQueryDto;
import com.hlkj.pay.dto.order.PayOrderQueryDto;
import com.hlkj.pay.dto.order.RefundOrderQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.mapper.order.OrderReceiveMapper;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.infrastructure.model.order.OrderReceiveDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.order.RefundOrderDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.service.CommonSnFilterService;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.service.order.IPayOrderService;
import com.hlkj.pay.service.order.IRefundOrderService;
import com.hlkj.pay.service.pay.IPayChannelService;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.task.CommonTasks;
import com.hlkj.pay.util.OrderCodeUtil;
import com.hlkj.pay.vo.admin.resp.user.AdminUserDetailResp;
import com.hlkj.pay.vo.openapi.order.resp.PayOrderSubmitApiResp;
import com.hlkj.pay.vo.order.req.*;
import com.hlkj.pay.vo.order.resp.PayOrderDetailResp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2025/01/07 11:22
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Validated
public class ReceiveOrderAppServiceImpl extends CommonSnFilterService implements IReceiveOrderAppService {

    private final IPayOrderService payOrderService;

    private final IRefundOrderService refundOrderService;

    private final IMerchantService merchantService;

    private final IPayChannelService payChannelService;

    private final IPayWayService payWayService;

    private final IPayOrderAppService payOrderAppService;

    private final IMerchantApplicationService merchantApplicationService;

    private final OrderCodeUtil orderCodeUtil;

    private final OrderReceiveMapper orderReceiveMapper;

    private final IAdminUserAppService adminUserAppService;

    private final CommonTasks commonTasks;

    // 收款单单号前缀
    private static final String RECEIVE_NO_PREFIX = "RECPT";

    @Override
    public PageResult<OrderReceiveDto> queryPage(OrderReceiveQueryDto receiveQueryDto) {
        IPage<OrderReceiveDto> mpPage = MyBatisUtils.buildPage(receiveQueryDto);
        QueryWrapper<OrderReceiveDto> queryWrapper = buildInfoWrapper(receiveQueryDto);
        orderReceiveMapper.selectPage(mpPage, queryWrapper);
        List<OrderReceiveDto> result = mpPage.getRecords();
        // 更新状态
        for(OrderReceiveDto orderReceiveDto:result){
            updateOrderReceiveDto(orderReceiveDto);
        }
        return new PageResult(result, mpPage.getTotal(), mpPage.getCurrent(), mpPage.getSize(), mpPage.getPages());
    }

    @Override
    public PageResult<PayOrderDetailResp> queryPayPage(PayOrderQueryDto payOrderQueryDto) {
        PageResult<PayOrderDO> page = payOrderService.queryPage(payOrderQueryDto);
        List<PayOrderDO> list = page.getList();
        if (CollectionUtils.isEmpty(list)) {
            PageResult<PayOrderDetailResp> result = buildPageResult(page, Collections.emptyList());
            return result;
        }
        List<PayOrderDetailResp> detailResps = BeanUtil.copyToList(list,PayOrderDetailResp.class);
        detailResps.stream().forEach(payOrderDetail -> {
            PayChannelDO payChannelDO = payChannelService.queryByCode(payOrderDetail.getChannelCode());
            if(payChannelDO != null){
                payOrderDetail.setChannelName(payChannelDO.getName());
            }
        });
        return buildPageResult(page, detailResps);
    }

    @Override
    public CommonResult<PayOrderSubmitApiResp> submitReceiveOrder(@Valid ReceiveOrderParamReq orderParamReq) {
        log.info("提交收款单 原始请求参数:{}", JsonUtils.toJsonString(orderParamReq));
        try {

            if(StrUtil.isEmpty(orderParamReq.getPayType()) || StrUtil.isEmpty(orderParamReq.getPaySubType())){
                return CommonResult.error(OpenApiResultCode.PAY_WAY_NOT_EFFECT);
            }
            // 收款单信息
            OrderReceiveDO orderReceiveDO = selectByCode(orderParamReq.getCode());
            MerchantAppDO merchantAppDO = merchantApplicationService.queryDetailByAppId(orderReceiveDO.getAppId());
            if (merchantAppDO == null) {
                return CommonResult.error(OpenApiResultCode.MERCHANT_APP_NOT_EXIST);
            }
            if (CommonEnum.YES_NO_TYPE.NO.getCode().equals(merchantAppDO.getStatus())) {
                return CommonResult.error(OpenApiResultCode.MERCHANT_APP_NOT_EFFECT);
            }
            String sn = orderReceiveDO.getSn();
            if(StrUtil.isEmpty(sn)){
                return CommonResult.error(OpenApiResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(sn);
            if (merchantInfoDO == null) {
                return CommonResult.error(OpenApiResultCode.MERCHANT_NOT_EXIST);
            }
            if (CommonEnum.YES_NO_TYPE.NO.getCode().equals(merchantInfoDO.getStatus())) {
                return CommonResult.error(OpenApiResultCode.MERCHANT_NOT_EFFECT);
            }
            if(orderReceiveDO == null){
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            if(orderReceiveDO.getStatus() == CommonEnum.YES_NO_TYPE.NO.getCode()){
                return CommonResult.error(MerchantResultCode.MERCHANT_RECEIVE_ORDER_CLOSED);
            }
            // 次数限制
            Integer limit = orderReceiveDO.getNum();
            if(limit != null){
                // 支付成功和支付中都计数
                Set<Integer> status = new HashSet<>();
                status.add(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                // status.add(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                List<PayOrderDO> payOrderDOList = getPayOrderList(status,orderParamReq.getCode());
                if(CollUtil.isNotEmpty(payOrderDOList) && payOrderDOList.size() >= limit){
                    return CommonResult.error(MerchantResultCode.MERCHANT_RECEIVE_ORDER_LIMIT);
                }
            }
            // 收集信息校验
            if(StrUtil.isNotEmpty(orderParamReq.getColletJson())){
                try{
                    // 合法性校验
                    if(!validCollectJson(orderParamReq.getColletJson(),true)){
                        return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单收集信息不合法");
                    }
                    // 校验收集信息属性是否合法
                    List<ReceiveOrderCollectReq> collectDbList = JSONUtil.toList(orderReceiveDO.getColletJson(),ReceiveOrderCollectReq.class);
                    // 过滤必填字段
                    List<String> requiredLabels = collectDbList.stream().filter(colletInfo ->colletInfo.getFlag() != null && colletInfo.getFlag() == true).map(ReceiveOrderCollectReq::getName).collect(Collectors.toList());
                    if(CollUtil.isNotEmpty(requiredLabels)){
                        // 收集信息参数校验  label和value有值
                        List<ReceiveOrderCollectBaseReq> collectReqList = JSONUtil.toList(orderParamReq.getColletJson(),ReceiveOrderCollectBaseReq.class);
                        for(String label:requiredLabels){
                            // 判断label是否存在
                            ReceiveOrderCollectBaseReq collectReq = CollUtil.findOneByField(collectReqList,"name",label);
                            if(collectReq == null){
                                return CommonResult.error(MerchantResultCode.MERCHANT_RECEIVE_ORDER_COLLETINFO_ERROR.getCode(),label+"必填");
                            }
                            // 判断value是否存在
                            if(StrUtil.isEmpty(collectReq.getField())){
                                return CommonResult.error(MerchantResultCode.MERCHANT_RECEIVE_ORDER_COLLETINFO_ERROR.getCode(),label+"必填");
                            }
                        }
                    }

                }catch (Exception e){
                    return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单收集信息不合法");
                }
            }
            // 收款单金额类型校验
            if(orderReceiveDO.getAmountType() == null){
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单金额类型必填");
            }

            // 获取支付方式
            PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByType(orderParamReq.getPayType());
            if (payType == null) {
                log.info("提交的支付类型错误:{}", orderReceiveDO.getPayType());
                return CommonResult.error(OpenApiResultCode.PAY_WAY_NOT_EXITS);
            }
            PayEnums.SCENE_PAY_TYPE scenePayType = PayEnums.SCENE_PAY_TYPE.fromByType(orderParamReq.getPaySubType());
            if (scenePayType == null) {
                log.info("提交的支付方式错误:{}", orderReceiveDO.getPaySubType());
                return CommonResult.error(OpenApiResultCode.PAY_WAY_NOT_EXITS);
            }

            // 获取支付方式
            PayWayDO payWayDO = payWayService.queryByType(payType.getCode(), scenePayType, orderReceiveDO.getSceneType());
            if (payWayDO == null) {
                return CommonResult.error(OpenApiResultCode.PAY_WAY_NOT_EXITS);
            }
            if (CommonEnum.YES_NO_TYPE.NO.getCode().equals(payWayDO.getStatus())) {
                return CommonResult.error(OpenApiResultCode.PAY_WAY_NOT_EFFECT);
            }

            PayOrderParamReq payOrderParamReq = new PayOrderParamReq();
            payOrderParamReq.setPayWayCode(payWayDO.getCode());
            payOrderParamReq.setSceneType(payWayDO.getSceneType());
            payOrderParamReq.setPaySubType(payWayDO.getSubType());
            payOrderParamReq.setPayType(PayEnums.PAY_TYPE.fromByCode(payWayDO.getType()).getType());
            if(StrUtil.isEmpty(orderParamReq.getMchOrderNo())){
                payOrderParamReq.setMchOrderNo(orderCodeUtil.orderNo("M",2));
            }else{
                payOrderParamReq.setMchOrderNo(orderParamReq.getMchOrderNo());
            }

            if(orderReceiveDO.getAmountType() == 0){
                payOrderParamReq.setAmount(orderReceiveDO.getAmount().toString());
            }else{
                payOrderParamReq.setAmount(orderParamReq.getAmount());
            }

            payOrderParamReq.setSignType(orderReceiveDO.getSignType());
            payOrderParamReq.setColletJson(orderParamReq.getColletJson());
            payOrderParamReq.setRemark(orderParamReq.getOrderRemark());

            if (StrUtil.isNotEmpty(orderReceiveDO.getRemark())) {
                payOrderParamReq.setSubject(orderReceiveDO.getRemark());
                payOrderParamReq.setDescription(orderReceiveDO.getRemark());
            } else {
                payOrderParamReq.setSubject("收款单收款");
                payOrderParamReq.setDescription("收款单收款");
            }
            // 获取请求IP
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            payOrderParamReq.setClientIp(ServletUtil.getClientIP(request, null));
            payOrderParamReq.setOrderType(PayOrderEnums.PAY_ORDER_TYPE.RECEIPT);
            // 收款单关联编码
            payOrderParamReq.setRelationOrderNo(orderParamReq.getCode());
            // 额外参数
            PayOrderCommonParamReq.Extra extra = new PayOrderCommonParamReq.Extra();
            extra.setAuthCode(orderParamReq.getAuthCode());
            // 收款单小程序ID 由前端必传
            extra.setSubAppid(orderParamReq.getAppid());
            payOrderParamReq.setExtra(extra);

            String servletPath = request.getServletPath();
            if (StringUtils.isBlank(servletPath)) {
                servletPath = request.getPathInfo();
            }
            LocalMerchantRequest localMerchantRequest = new LocalMerchantRequest();
            localMerchantRequest.setStartTime(System.currentTimeMillis());
            localMerchantRequest.setRequestUrl(servletPath);
            localMerchantRequest.setSn(sn);
            localMerchantRequest.setMerchantAppDO(merchantAppDO);
            localMerchantRequest.setMerchantInfoDO(merchantInfoDO);
            localMerchantRequest.setRequestMethod(request.getMethod());
            LocalContext.set(localMerchantRequest);

            log.info("提交收款单 支付请求参数:{}", JsonUtils.toJsonString(payOrderParamReq));
            CommonResult<PayOrderSubmitApiResp> respCommonResult = payOrderAppService.submitOrder(payOrderParamReq);
            log.info("提交收款单 支付返回参数:{}", JsonUtils.toJsonString(respCommonResult));
            return respCommonResult;
        }
        catch (Exception e) {
            log.error("提交收款单 请求失败, message:{}", e);
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(), e.getMessage());
        }
    }

    @Override
    public CommonResult<OrderReceiveDO> saveReceiveOrder(ReceiveOrderSetReq ReceiveOrderSetReq) {
        log.info("saveReceiveOrder ReceiveOrderSetReq:{}", JsonUtils.toJsonString(ReceiveOrderSetReq));
        try {
            OrderReceiveDO orderReceiveDO = BeanUtil.copyProperties(ReceiveOrderSetReq,OrderReceiveDO.class);
            // 收款单默认微信小程序线下支付
            // if(StrUtil.isEmpty(orderReceiveDO.getPayType())){
            //     orderReceiveDO.setPayType(PayEnums.PAY_TYPE.WECHAT.getType());
            // }
            // if(StrUtil.isEmpty(orderReceiveDO.getPaySubType())){
            //     orderReceiveDO.setPaySubType(PayEnums.SCENE_PAY_TYPE.MINI_APP.getType());
            // }
            if(orderReceiveDO.getSceneType() == null){
                orderReceiveDO.setSceneType(PayEnums.SCENE_TYPE.OFFLINE.getCode());
            }
            if(orderReceiveDO.getAmountType() == null){
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单金额类型 不能为空");
            }
            // 收款方填写金额则金额必填
            if(orderReceiveDO.getAmountType() == 0 && orderReceiveDO.getAmount() == null){
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款方填写金额则金额必填");
            }
            // 收集信息校验
            if(StrUtil.isNotEmpty(orderReceiveDO.getColletJson())){
                try{
                    // 合法性校验
                    if(!validCollectJson(orderReceiveDO.getColletJson(),false)){
                        return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单收集信息不合法");
                    }
                }catch (Exception e){
                    return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),"收款单收集信息不合法");
                }
            }

            LocalAdminUserRequest request = (LocalAdminUserRequest)LocalContext.get();
            if(request == null){
                return CommonResult.error(OpenApiResultCode.MERCHANT_NOT_EXIST);
            }
            log.info("saveReceiveOrder LocalAdminUserRequest" +":{}", JsonUtils.toJsonString(request));

            if(StrUtil.isEmpty(request.getSn())){
                return CommonResult.error(OpenApiResultCode.MERCHANT_NOT_EXIST);
            }
            orderReceiveDO.setSn(request.getSn());
            // 通过sn获取吗，默认应用
            MerchantAppDO merchantAppDO = merchantApplicationService.queryDefaultApp(request.getSn());
            if(merchantAppDO == null){
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING.getCode(),request.getSn()+"默认应用 不能为空");
            }
            orderReceiveDO.setAppId(merchantAppDO.getAppId());

            // 收款单编码
            orderReceiveDO.setCode(orderCodeUtil.orderNo(RECEIVE_NO_PREFIX,2));
            orderReceiveDO.setStatus(PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.NOT_PAY.getCode());
            orderReceiveMapper.insert(orderReceiveDO);

            if(orderReceiveDO.getId() != null){
                // 更新二维码
                commonTasks.recptSyncQrData(orderReceiveDO.getId(),orderReceiveDO.getCode());
            }
            return CommonResult.success(orderReceiveDO);
        }
        catch (Exception e) {
            log.error("saveReceiveOrder error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<OrderReceiveDto> detail(String code) {
        OrderReceiveDO orderReceiveDO = selectByCode(code);
        if(orderReceiveDO == null){
            return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
        }
        OrderReceiveDto orderReceiveDto = BeanUtil.copyProperties(orderReceiveDO,OrderReceiveDto.class);

        CommonResult<AdminUserDetailResp> userDetailRespCommonResult = adminUserAppService.userDetail(Long.valueOf(orderReceiveDO.getCreatedBy()));
        if(userDetailRespCommonResult.isSuccess() && userDetailRespCommonResult.getData() != null){
            orderReceiveDto.setCreatedByName(userDetailRespCommonResult.getData().getUserName());
        }
        updateOrderReceiveDto(orderReceiveDto);
        return CommonResult.success(orderReceiveDto);
    }

    @Override
    public CommonResult<String> link(String code) {
        OrderReceiveDO orderReceiveDO = selectByCode(code);
        if(orderReceiveDO == null){
            return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
        }
        return CommonResult.success(orderReceiveDO.getLink());
    }

    @Override
    public CommonResult<Void> updateReceiveOrder(ReceiveOrderUpdateReq receiveOrderUpdateReq) {
        log.info("updateReceiveOrder receiveOrderUpdateReq:{}", JsonUtils.toJsonString(receiveOrderUpdateReq));
        try {
            OrderReceiveDO orderReceiveDO = orderReceiveMapper.selectById(receiveOrderUpdateReq.getId());
            if (orderReceiveDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderReceiveDO = BeanUtil.copyProperties(receiveOrderUpdateReq,OrderReceiveDO.class);
            orderReceiveMapper.updateById(orderReceiveDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateReceiveOrder error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updateStatus(ReceiveOrderUpdateReq receiveOrderUpdateReq) {
        log.info("updateReceiveOrder updateStatus:{}", JsonUtils.toJsonString(receiveOrderUpdateReq));
        try {
            OrderReceiveDO orderReceiveDO = orderReceiveMapper.selectById(receiveOrderUpdateReq.getId());
            if (orderReceiveDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderReceiveDO = new OrderReceiveDO();
            orderReceiveDO.setId(receiveOrderUpdateReq.getId());
            orderReceiveDO.setStatus(receiveOrderUpdateReq.getStatus());
            orderReceiveMapper.updateById(orderReceiveDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateStatus error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> syncStatus() {
        log.info("updateReceiveOrder syncStatus");
        LambdaQueryWrapperX<OrderReceiveDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.inIfPresent(OrderReceiveDO::getStatus, CollUtil.newArrayList(PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.NOT_PAY.getCode(),PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.PAY.getCode()));
        List<OrderReceiveDO> list = orderReceiveMapper.selectList(queryWrapper);
        if(CollUtil.isNotEmpty(list)){
            for(OrderReceiveDO orderReceiveDO:list){
                // 要查询的订单状态
                List<PayOrderDO> payOrderDOList = getPayOrderList(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode(),orderReceiveDO.getCode());
                if(CollUtil.isNotEmpty(payOrderDOList)){
                    Integer newStatus = null;
                    if(payOrderDOList.size() >= orderReceiveDO.getNum()){
                        newStatus = PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.FINISH.getCode();
                    }else {
                        newStatus = PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.PAY.getCode();

                    }
                    // 与数据库比较 不同则更新
                    if(newStatus != null && orderReceiveDO.getStatus() != newStatus ){
                        log.info("updateReceiveOrder syncStatus id={},oldStatus={},newStatus={}",orderReceiveDO.getId(),orderReceiveDO.getStatus(),newStatus);
                        OrderReceiveDO update = new OrderReceiveDO();
                        update.setId(orderReceiveDO.getId());
                        update.setStatus(newStatus);
                        orderReceiveMapper.updateById(update);
                    }
                }

            }
        }
        return CommonResult.success();
    }


    public OrderReceiveDO selectByCode(String code) {
        LambdaQueryWrapperX<OrderReceiveDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(OrderReceiveDO::getCode, code);
        return  orderReceiveMapper.selectOne(queryWrapper);
    }

    /**
     * 更新收款单计数和状态
     * @param orderReceiveDto
     */
    public void updateOrderReceiveDto(OrderReceiveDto orderReceiveDto){

        // 是否更新状态
        boolean updateStatus = true;
        if(orderReceiveDto.getStatus() == PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.CLOSED.getCode() ||
                orderReceiveDto.getStatus() == PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.FINISH.getCode() ){
            updateStatus = false;
        }

        // 要查询的订单状态
        List<PayOrderDO> payOrderDOList = getPayOrderList(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode(),orderReceiveDto.getCode());
        if(CollUtil.isNotEmpty(payOrderDOList)){
            if(updateStatus){
                Integer newStatus = null;
                if(payOrderDOList.size() >= orderReceiveDto.getNum()){
                    newStatus = PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.FINISH.getCode();
                }else {
                    newStatus = PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.PAY.getCode();

                }
                // 与数据库比较 不同则更新
                if(newStatus != null && orderReceiveDto.getStatus() != newStatus ){
                    OrderReceiveDO orderReceiveDO = new OrderReceiveDO();
                    orderReceiveDO.setId(orderReceiveDto.getId());
                    orderReceiveDO.setStatus(newStatus);
                    orderReceiveMapper.updateById(orderReceiveDO);
                }
                orderReceiveDto.setStatus(newStatus);
            }
            orderReceiveDto.setPayNum(payOrderDOList.size());
            // 计算总金额 支付金额-退款金额
            Double totalAmount = payOrderDOList.stream().mapToDouble(payOrder-> payOrder.getAmount().doubleValue()-payOrder.getRefundAmount().doubleValue()).sum();
            if(totalAmount < 0 ){
                totalAmount = 0D;
            }
            orderReceiveDto.setTotalAmount(new BigDecimal(totalAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
        }else{
            if(updateStatus){
                orderReceiveDto.setStatus(PayOrderEnums.PAY_ORDER_RECEIVE_STATUS.NOT_PAY.getCode());
            }
            orderReceiveDto.setPayNum(0);
            orderReceiveDto.setTotalAmount(new BigDecimal(0));
        }
    }

    /**
     * 校验收集信息合法性
     * @param colletJson
     * @param base  是否基础字段，下单时校验
     * @return
     */
    public boolean validCollectJson(String colletJson , boolean base){
        if(StrUtil.isEmpty(colletJson)){
            return true;
        }
        // 转数组
        JSONArray colletJsonArr = JSONUtil.parseArray(colletJson);
        // 获取对象
        Object collect =  colletJsonArr.get(0);
        // 对象转为Map
        Map<String, Object> beanToMap = new HashMap<>();
        beanToMap = BeanUtil.beanToMap(collect, beanToMap, CopyOptions.create());
        // map判断key是否存在
        boolean name = beanToMap.containsKey("name");
        boolean field = beanToMap.containsKey("field");
        boolean checked = beanToMap.containsKey("checked");
        boolean flag = beanToMap.containsKey("flag");
        if(base){
            if(!name || !field ){
                return false;
            }
        }else{
            if(!name || !field  || !checked  || !flag ){
                return false;
            }
        }
        return true;
    }

    /**
     * 获取关联下单信息
     * @param status 订单状态集合
     * @param code   创建单编码
     * @return
     */
    public List<PayOrderDO>  getPayOrderList(Set<Integer> status,String code){
        // 查询关联的订单信息
        PayOrderQueryDto payOrderQueryDto = new PayOrderQueryDto();
        payOrderQueryDto.setRelationOrderNo(code);
        payOrderQueryDto.setStates(status);
        List<PayOrderDO> payOrderDOList = payOrderService.queryList(payOrderQueryDto);
        for(PayOrderDO payOrderDO : payOrderDOList){
            RefundOrderQueryDto refundOrderQueryDto = new RefundOrderQueryDto();
            refundOrderQueryDto.setPayOrderNo(payOrderDO.getPayOrderNo());
            List<RefundOrderDO> refundOrderDOList = refundOrderService.queryList(refundOrderQueryDto);
            if(CollUtil.isEmpty(refundOrderDOList)){
                payOrderDO.setRefundAmount(new BigDecimal(0));
            }else{
                Double totalAmount = refundOrderDOList.stream().filter(refundOrderDO -> refundOrderDO.getRefundStatus() == PayOrderEnums.REFUND_STATUS.REFUND.getCode()).mapToDouble(payOrder->payOrder.getRefundAmount().doubleValue()).sum();
                payOrderDO.setRefundAmount(new BigDecimal(totalAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
            }
        }
        return payOrderDOList;
    }

    public List<PayOrderDO>  getPayOrderList(Integer status,String code){
        // 查询关联的订单信息
        PayOrderQueryDto payOrderQueryDto = new PayOrderQueryDto();
        payOrderQueryDto.setRelationOrderNo(code);
        payOrderQueryDto.setState(status);
        List<PayOrderDO> payOrderDOList = payOrderService.queryList(payOrderQueryDto);
        return payOrderDOList;
    }

    QueryWrapper<OrderReceiveDto> buildInfoWrapper(OrderReceiveQueryDto receiveQueryDto) {
        filterSn(receiveQueryDto);
        QueryWrapperX<OrderReceiveDto> queryWrapper = new QueryWrapperX<>();
        queryWrapper.eq("a.delete_flag", CommonEnum.YES_NO_TYPE.NO.getCode());
        queryWrapper.likeIfPresent("a.name", receiveQueryDto.getName());
        queryWrapper.eqIfPresent("a.sn", receiveQueryDto.getSn());
        queryWrapper.inIfPresent("a.sn", receiveQueryDto.getSnList());
        queryWrapper.eqIfPresent("a.status", receiveQueryDto.getStatus());
        queryWrapper.likeIfPresent("a.code", receiveQueryDto.getCode());
        queryWrapper.likeIfPresent("a.app_id", receiveQueryDto.getAppId());
        queryWrapper.geIfPresent("a.create_time", receiveQueryDto.getStartQueryTime());
        queryWrapper.leIfPresent("a.create_time", receiveQueryDto.getEndQueryTime());
        return queryWrapper;
    }

    public PageResult<PayOrderDetailResp> buildPageResult(PageResult pageResult, List<PayOrderDetailResp> list) {
        PageResult<PayOrderDetailResp> result = new PageResult<>();
        result.setPageNo(pageResult.getPageNo());
        result.setPageSize(pageResult.getPageSize());
        result.setPages(pageResult.getPages());
        result.setTotal(pageResult.getTotal());
        result.setList(list);
        return result;
    }

}
